package com.wechat.server.mp.util;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.extra.ssh.Sftp;
import com.osr.jni.smx.SMXlib;
import com.osr.jni.smx.SMXlibConstant;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @description: 移动的工具测试
 * @author: stone
 * @date: Created by 2024/3/25 16:35
 * @version: 1.0.0
 * @pakeage: com.wechat.server.mp.util
 */
@Slf4j
public class YiDongUtil {


    /**
     * 通过项目路径获取解密文件内容
     *
     * @param filePath
     * @param fileName
     * @return
     * @throws Exception
     */
    public static List<String> gmFileDencrypt(String filePath, String fileName, String prvKey) throws Exception {
        List<String> contentList = new ArrayList<>();

        log.info("路径{}，文件{}", filePath, fileName);
        File secretfile = new File(filePath + File.separator + "GmKeyCiphertext");
        if (!secretfile.exists()) {
            log.error("临时秘钥文件不存在路径为：" + filePath + File.separator + "GmKeyCiphertext");
            return contentList;
        }
        InputStream is = new FileInputStream(secretfile);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();//输出流
        String dataStr = "";
        byte[] bytes = new byte[1024];
        int len;
        if (is != null) {
            while ((len = is.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);//将读到的字节写入输出流
            }
            dataStr = outputStream.toString();
            is.close();
        }
        outputStream.close();
        // 获取临时密钥明文
        String secret = gmSM2DencryptKey(prvKey, dataStr);
        log.info("密钥：" + secret);
        // 解密文件
        contentList = gmSM4Dencrypt(secret, filePath + File.separator + fileName);
//        FileEncryption.gmSM4DencryptToFile(secret,filePath+File.separator+fileName);
        log.info(contentList.size() + "");
        return contentList;
    }


    /**
     * 通过项目路径获取解密文件内容
     *
     * @param filePath
     * @param fileName
     * @return
     * @throws Exception
     */
    public static List<String> gmFileDencryptSftp(String filePath, String fileName, String prvKey) {
        List<String> contentList = new ArrayList<>();
        log.info("路径={}，文件={}", filePath, fileName);

        Sftp bean = SpringUtil.getBean(Sftp.class);
        String dataStr;
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            bean.download(filePath + "/GmKeyCiphertext", outputStream);
            dataStr = outputStream.toString();
        } catch (IOException e) {
            log.error("关闭输出流异常{}", fileName, e);
            return contentList;
        }

        // 获取临时密钥明文
        String secret = gmSM2DencryptKey(prvKey, dataStr);
        log.info("密钥：" + secret);

        try (ByteArrayOutputStream outputFileStream = new ByteArrayOutputStream()) {//输出流
            // 解密文件
            bean.download(filePath + fileName, outputFileStream);
            String string = gmSM4DencryptData(secret, outputFileStream.toString());
            log.info("解密过来的值是{}", string);
            contentList = Arrays.asList(string.split(LINE_SEPARATOR));
        } catch (IOException e) {
            log.error("关闭输出流异常{}", fileName, e);
        } finally {
            bean.close();
        }

//        FileEncryption.gmSM4DencryptToFile(secret,filePath+File.separator+fileName);
        log.info("获取到行数为{}", contentList.size());
        return contentList;
    }

    /**
     * 使用私钥解密临时对称密钥密文，得到对称密钥明文
     *
     * @param prvKey
     * @param dataStr
     * @return
     */
    public static String gmSM2DencryptKey(String prvKey, String dataStr) {
        SMXlib gmLib = SMXlib.getInstance();
        String filePath = gmLib.SM2Dencrypt(prvKey, dataStr);
        return filePath.substring(0, 32);
    }

    public static List<String> gmSM4Dencrypt(String secret, String filePath) throws Exception {
        String line;
        BufferedReader br = new BufferedReader(new FileReader(filePath));
        SMXlib gmLib = SMXlib.getInstance();
        List<String> list = new ArrayList<>();
        while ((line = br.readLine()) != null) {
            //解密数据，参数：对称密钥明文，密文数据
            byte[] data = gmLib.SM4DencryptToByte(secret, line);
            //do something....
            //比如转成字符串
            list.add(new String(data, SMXlibConstant.DEFAULT_CHARSET));
        }

        return list;
    }


    static String LINE_SEPARATOR = "\\r?\\n";

    public static String gmSM4DencryptData(String secret, String dataStr) {

        SMXlib gmLib = SMXlib.getInstance();
        //解密数据，参数：对称密钥明文，密文数据
        byte[] data = gmLib.SM4DencryptToByte(secret, dataStr);
        //do something....dataStr
        //比如转成字符串
        return new String(data, SMXlibConstant.DEFAULT_CHARSET);
    }
}
